#ifndef _WIN32 // Linux like os.

#include <string.h>
#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include "share_mem.h"

namespace anet {
	namespace SShareMemorySpace {
		// create share memory
		bool CShareMemory::CreateShareMem(key_t key, size_t memSize) {
			if (m_pshm != nullptr) { // if the memory is not null, just return.
				return true;
			}
			m_create = true;

			// try to create share memory
			if ((m_shmId = shmget(key, memSize, IPC_CREAT | IPC_EXCL | 0666)) < 0) {
				return false;
			}

			// try to attach share memory
			if ((m_pshm = shmat(m_shmId, nullptr, 0)) == (char *)-1) {
				return false;
			}

			m_shmSize = memSize;
			m_shmKey = key;
			return true;
		}

		bool CShareMemory::OpenShareMem(key_t key, size_t memSize) {
			if (m_pshm != nullptr) { // if the memory is not null, just return.
				return true;
			}
			m_create = false;

			// try to get share memory.
			if ((m_shmId = shmget(key, memSize, 0666)) < 0) {
				return false;
			}

			// try to attach share memory.
			if ((m_pshm = shmat(m_shmId, nullptr, 0)) == (char *)-1) {
				return false;
			}
			m_shmSize = memSize;
			m_shmKey = key;
			return true;
		}

		int CShareMemory::Delete() {
			int retCode = 0;
			if (m_pshm != nullptr) {
				retCode = shmctl(m_shmId, IPC_RMID, 0);
				m_pshm = nullptr;
			}
			return retCode;
		}

		int CShareMemory::Detach() {
			int retCode = 0;
			if (m_pshm != nullptr) {
				retCode = shmdt(m_pshm);
				m_pshm = nullptr;
			}
			return retCode;
		}
	}
}

#endif